#include "SearchField.h"
#include "ListPanel.h"
#include <iostream>
using namespace std;

SearchField::SearchField(ListPanel* lp, String str) :
	panel(lp), focused(false), blink(false), selectingAll(false), defaultString(str) {
	setWantsKeyboardFocus(true);
	startTimer(400);
}

void SearchField::setText(const String& text) {
	searchString = text;
	String token;
	vector<String> list;

	if (text.contains(T(" "))) {
		tokenize(searchString, list);
	} else {
		list.push_back(text);
	}

	if (list.size())
		panel->filterList(list);

	repaint();
}

bool SearchField::keyPressed(const KeyPress& k) {
	if (k.getKeyCode() == KeyPress::backspaceKey) {
		if (searchString.length() > 0) {
			if (selectingAll) {
				searchString = String::empty;
				selectingAll = false;
			} else {
				searchString = searchString.substring(0, searchString.length() - 1);
			}
			setText(searchString);
		} else
			setText(String::empty);
	} else {
		if (selectingAll) {
			searchString = String::empty;
			selectingAll = false;
		}
		setText(searchString += k.getTextCharacter());
	}
	panel->repaint();
	return true;
}

void SearchField::paint(Graphics& g) {
	Font sansSerif(Font::getDefaultSansSerifFontName(), 18, Font::plain);
	g.setFont(sansSerif);
	g.fillAll(Colours::white);
	if (focused)
		g.setColour(Colours::orange);
	g.drawRect(0, 0, getWidth(), getHeight());

	if (selectingAll) {
		g.setColour(Colour(80, 90, 140));
		g.fillRect(15, 3, sansSerif.getStringWidth(searchString), getHeight() - 6);
	}
	g.setColour(selectingAll ? Colours::white : Colours::darkgrey);
	if (searchString.length() > 0 || focused)
		g.drawSingleLineText(searchString, 15, getHeight() / 2 + 6);
	else
		g.drawSingleLineText(defaultString, 15, getHeight() / 2 + 6);

	g.setColour(Colours::darkgrey);
	if (focused && blink) {
		g.drawVerticalLine(sansSerif.getStringWidth(searchString) + 15, 3, getHeight() - 3);
	}
}

void SearchField::focusGained(FocusChangeType cause) {
	focused = true;
	repaint();
}

void SearchField::focusLost(FocusChangeType cause) {
	focused = false;
	selectingAll = false;
	repaint();
}

void SearchField::timerCallback() {
	if (!selectingAll) {
		blink ^= 1;
		repaint();
	}
}

void SearchField::mouseDoubleClick(const MouseEvent& e) {
	selectingAll = true;
	blink = false;
	repaint();
}

void SearchField::mouseDown(const MouseEvent& e) {
	if (searchString.length() > 0)
		selectingAll ^= 1;
	blink = !selectingAll;
	repaint();
}

void SearchField::tokenize(String& s, vector<String>& list) {
	list.clear();
	list.push_back(T(""));
	for (int i = 0; i < s.length(); i++) {
		if (s[i] == L' ') {
			list.push_back(T(""));
		} else {
			list.back() += s[i];
		}
	}
	if (list.back() == T("")) {
		list.pop_back();
	}
}
